﻿using SignalBox.Core.Model;
using SignalBox.Core.Model.Graph;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace SignalBox.Core.UI
{
    public class LayoutPanel : System.Windows.Forms.Panel
    {

        private Rectangle selRect;


        public LayoutPanel()
        {
            DoubleBuffered = true;
        }

        public TrackLayout TrackLayout
        {
            get;
            set;
        }


        public List<Train> Trains
        {
            get;
            set;
        }


        public void SetSelection(Rectangle rect)
        {
            selRect = rect;
            Invalidate();

        }

        public void SetSelection(Point p1, Point p2)
        {
            if (p1 == Point.Empty || p2 == Point.Empty)
            {
                selRect = Rectangle.Empty;
                Invalidate();
                return;

            }

            selRect = new Rectangle() { Location = new Point(Math.Min(p1.X, p2.X), Math.Min(p1.Y, p2.Y)), Size = new Size(Math.Abs(p1.X - p2.X), Math.Abs(p1.Y - p2.Y)) };
            Invalidate();

        }

        public void ClearSelection()
        {
            selRect = Rectangle.Empty;
            Invalidate();
        }

        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        {

            if (TrackLayout == null) return;

            this.AutoScrollMinSize = new Size(TrackLayout.Cols * TrackLayout.PIXELSPERCELL, TrackLayout.Rows * TrackLayout.PIXELSPERCELL);
            e.Graphics.Clear(Color.White);
            e.Graphics.TranslateTransform(AutoScrollPosition.X, AutoScrollPosition.Y);
            if (TrackLayout.ShowGrid)
            {
                PaintGrid(e.Graphics);
            }

            PaintLayout(e.Graphics);
            PaintSelection(e.Graphics);
            PaintTrains(e.Graphics);
#if DEBUG
            PaintGraph(e.Graphics);
#endif
            base.OnPaint(e);

        }

#if DEBUG

        private void PaintGraph(Graphics g)
        {
            SignalGraph sg = new SignalGraph(TrackLayout);
            foreach (SignalNode sn in sg.Signals)
            {
                if (sn.NextSignal != null)
                {
                    g.DrawLine(new Pen(Color.Blue), sn.Cell.X * TrackLayout.PIXELSPERCELL, sn.Cell.Y * TrackLayout.PIXELSPERCELL, sn.NextSignal.Cell.X * TrackLayout.PIXELSPERCELL, sn.NextSignal.Cell.Y * TrackLayout.PIXELSPERCELL);
                }
            }
        }

#endif

        public Point GetCell(Point args)
        {
            Point p = new Point(-AutoScrollPosition.X + args.X, -AutoScrollPosition.Y + args.Y);

            return new Point(p.X / TrackLayout.PIXELSPERCELL, p.Y / TrackLayout.PIXELSPERCELL);
        }

        protected override void OnScroll(System.Windows.Forms.ScrollEventArgs se)
        {
            base.OnScroll(se);
            Invalidate();
        }

        private void PaintTrains(Graphics g)
        {
            if (Trains == null) return;

            Font f = new Font("Verdana", 8);
            Brush b = new SolidBrush(Color.Black);

            foreach (Train t in Trains)
            {
                string code = t.TrainCode;

                if (t.State != Train.TrainState.NOT_AVAILABLE && t.State != Train.TrainState.LEFT)
                {
                    g.DrawString(code, f, b, t.HeadLocation.X * TrackLayout.PIXELSPERCELL, t.HeadLocation.Y * TrackLayout.PIXELSPERCELL);
                }
            }
        }

        private void PaintSelection(Graphics g)
        {
            if (selRect == Rectangle.Empty)
                return;

            int ppc = TrackLayout.PIXELSPERCELL;

            Rectangle drawRect = new Rectangle() { X = selRect.X * ppc, Y = selRect.Y * ppc, Width = (selRect.Width + 1)*ppc, Height = (selRect.Height + 1)*ppc };


            g.DrawRectangle(new Pen(new SolidBrush(Color.Blue)), drawRect);
        }

        private void PaintLayout(Graphics g)
        {
            for (int x = 0; x < TrackLayout.Cols; x++)
            {
                for (int y = 0; y < TrackLayout.Rows; y++)
                {
                    TrackCell tc = TrackLayout.getCell(x, y);
                    if (tc != null)
                    {
                        tc.drawCell(g);
                    }
                }
            }
        }

        private void PaintGrid(Graphics g)
        {
            Brush b = new SolidBrush(Color.LightGray);
            Pen p = new Pen(b);

            for (int x = 1; x < TrackLayout.Cols; x++)
            {

                g.DrawLine(p, x * TrackLayout.PIXELSPERCELL, 0, x * TrackLayout.PIXELSPERCELL, TrackLayout.Rows * TrackLayout.PIXELSPERCELL);

            }

            for (int y = 1; y < TrackLayout.Rows; y++)
            {
                g.DrawLine(p, 0, y * TrackLayout.PIXELSPERCELL, TrackLayout.Cols * TrackLayout.PIXELSPERCELL, y * TrackLayout.PIXELSPERCELL);
            }

            p.Dispose();
            b.Dispose();
        }
    }
}
